// 数据列表请求接口封装
import { isPromiseLike } from '@inbiz/utils';
import { request } from '@inbiz/utils';
const version = InbizConfig.API_VERSION
import { useRequest } from 'ahooks';
import type { MutableRefObject } from 'react';
type options = {
  defaultParams?: [IParams];
  onBefore?: (params: [IParams]) => void;
  onSuccess?: (data: object, params: [IParams]) => void;
  onError?: (e: Error, params: [IParams]) => void;
  onFinally?: (params: [IParams], data?: object, e?: Error) => void;
};

type IParams = {
  appId: string;
  key: string;
  pageIndex: number;
  pageSize: number;
  filterLazy?: string;
  conditions?: {
    index: number;
    connector: Required<Iparams>['conditions'][number]['connector'];
    condition: {
      connector: Required<Iparams>['conditions'][number]['connector'];
      operator: Required<
        Required<Iparams>['conditions'][number]['condition']
      >[number]['operator'];
      field: string;
      value?: unknown;
    }[];
  }[];
};

type events = MutableRefObject<{
  onParamFormat?: <T>(param: T) => T;
  onData?: <T>(data: T) => T;
  onRequest?: typeof queryData;
}>;

const useListRequest = <T extends events>(
  events: T,
  options?: options,
  emit?: any,
) => {
  const result = useRequest(
    ({ appId, key, pageIndex, pageSize, conditions, filterLazy }: IParams) => {
      const paramData = {
        filterLazy,
        appId,
        key,
        pageInfo: {
          index: pageIndex,
          size: pageSize,
        },
        conditions: [] as Required<Iparams>['conditions'],
      };
      if (conditions && conditions.length) {
        conditions.forEach(({ condition, ...other }) => {
          let group = {
            ...other,
            condition: [],
          } as Required<Iparams>['conditions'][number];
          condition.forEach(({ value, field, ...item }) => {
            if (value) {
              let modelName, fieldName;
              if (field.indexOf('$') != -1) {
                [modelName, fieldName] = field.split('$');
              } else {
                fieldName = field;
                modelName = '';
              }
              group.condition.push({
                value,
                field: fieldName,
                modelName,
                ...item,
              });
            }
          });
          if (group.condition.length) {
            paramData.conditions.push(group);
          }
        });
      }
      const newparamData =
        events?.current.onParamFormat?.(paramData) || paramData;
      const reuslt = events?.current.onRequest
        ? events.current.onRequest(newparamData)
        : queryData(newparamData);
      if (isPromiseLike(reuslt)) {
        reuslt
          .then((res) => {
            if (res) {
              if (res?.Rows?.length) {
                res.Rows.forEach(formatListData);
                res = events?.current.onData?.(res) || res;
              }
              emit?.('onSuccess', res);
            } else {
              emit?.('onError');
            }
            return res;
          })
          .catch(() => {
            emit?.('onError');
          });
      }
      return reuslt;
    },
    {
      ...options,
      manual: true,
    },
  );
  return result;
};
export default useListRequest;

const valutToString = (value: { label?: string } | { label?: string }[]) => {
  let newValue = '';
  if (Array.isArray(value)) {
    newValue = value.map((item) => item.label).join(',');
    if (!newValue) {
      newValue = value.join(',');
    }
  } else {
    newValue = value.label ? value.label : JSON.stringify(value);
  }
  return newValue;
};
// 格式化返回的数据
export const formatListData = (item: {
  [key: string]: string | number | boolean | { IsLazy?: boolean } | object[];
}) => {
  Object.entries(item).forEach(([key, value]) => {
    if (value && item[`$_${key}_original`] === undefined) {
      if (
        typeof value === 'object' &&
        (Array.isArray(value) || value.IsLazy === undefined)
      ) {
        item[`$_${key}_original`] = value;
        item[key] = valutToString(
          value as { label?: string } | { label?: string }[],
        );
      }
      if (typeof value === 'string' && value.length >= 2) {
        const first = value[0],
          last = value.slice(-1);
        if (
          (first === '{' && last === '}') ||
          (first === '[' && last === ']')
        ) {
          try {
            const parseValue = JSON.parse(value);
            item[`$_${key}_original`] = parseValue;
            item[key] = valutToString(parseValue);
          } catch {
            // console.error(`${key}模型字段序列化失败!序列化内容:`, value);
          }
        }
      }
    }
  });
};

type Iparams = {
  appId: string;
  key: string;
  pageInfo: {
    index: number;
    size: number;
  };
  conditions?: {
    index: number;
    connector: 'and' | 'or';
    condition: {
      connector: 'and' | 'or';
      modelName: string;
      field: string;
      operator:
        | 'eq'
        | 'neq'
        | 'gt'
        | 'get'
        | 'lt'
        | 'lte'
        | 'like'
        | 'nlike'
        | 'nstartwith'
        | 'startwith'
        | 'endwith'
        | 'nendwith'; //| 'in' | 'nin',
      value?: unknown;
    }[];
  }[];
};

async function queryData(params: Iparams): Promise<{
  Success: number;
  Total: number;
  Rows: {
    [key: string]: string | number | boolean | { IsLazy?: boolean } | object[];
  }[];
}> {
  return request.post(
    `/inbiz/api/services/front/modelengine/v${version}/modelQueryAdapter/queryDatas`,
    {
      timeout: 10000,
      data: {
        ...params,
        appId: params.appId ? params.appId : params.appId || '',
      },
    },
  );
}
type IDataChildParams = {
  appId: string;
  masterModelKey: string;
  childModelKey: string;
  queryKey: string;
  recordId: string;
  pageIndex: number;
  pageSize: number;
};

async function queryChildData(params: IDataChildParams): Promise<{
  Success: number;
  Total: number;
  Rows: {
    [key: string]: string | number | boolean | { IsLazy?: boolean } | object[];
  }[];
}> {
  return request.get('/inbiz/api/services/modelengine/v3/model/dataChild', {
    params: {
      ...params,
      version,
    },
  });
}
type childEvents = MutableRefObject<{
  onChildParamFormat?: <T>(param: T) => T;
  onChildDataLoad?: <T>(data: T) => T;
  onChildRequest?: typeof queryChildData;
}>;

type IChildOptions = {
  defaultParams?: Parameters<typeof queryChildData>;
  onBefore?: (params: Parameters<typeof queryChildData>) => void;
  onSuccess?: (data: object, params: Parameters<typeof queryChildData>) => void;
  onError?: (e: Error, params: Parameters<typeof queryChildData>) => void;
  onFinally?: (
    params: Parameters<typeof queryChildData>,
    data?: object,
    e?: Error,
  ) => void;
};

// 表格子表
const useChildListRequest = <T extends childEvents>(
  events: T,
  options?: IChildOptions,
) => {
  const result = useRequest(
    (params: Parameters<typeof queryChildData>[0]) => {
      const newparamData =
        events?.current.onChildParamFormat?.(params) || params;
      const reuslt = events?.current.onChildRequest
        ? events.current.onChildRequest(newparamData)
        : queryChildData(newparamData);
      if (isPromiseLike(reuslt)) {
        reuslt.then((res) => {
          if (res?.Rows?.length) {
            res.Rows.forEach(formatListData);
            res = events?.current.onChildDataLoad?.(res) || res;
          }
          return res;
        });
      }
      return reuslt;
    },
    {
      ...options,
      manual: true,
    },
  );
  return result;
};
export { useChildListRequest };
export type { queryData, queryChildData };
